Padroneggia l'API Temporal di JavaScript per la gestione moderna di date e orari. Impara a sostituire gli oggetti Date legacy con un'API potente, intuitiva e consapevole del fuso orario.
API Temporal di JavaScript: Manipolazione Moderna di Date e Orari
L'oggetto Date di JavaScript è stato a lungo una fonte di frustrazione per gli sviluppatori. La sua mutabilità, la mancanza di supporto integrato per il fuso orario e l'API scomoda hanno portato a innumerevoli librerie e soluzioni alternative. Fortunatamente, l'API Temporal mira a risolvere queste carenze, fornendo una soluzione moderna, intuitiva e consapevole del fuso orario per la manipolazione di date e orari in JavaScript.
Cos'è l'API Temporal?
L'API Temporal è un nuovo oggetto globale, Temporal, che fornisce un modo moderno e standardizzato per lavorare con date e orari in JavaScript. È progettato per sostituire l'oggetto legacy Date, offrendo miglioramenti significativi in termini di progettazione dell'API, immutabilità, supporto del fuso orario e usabilità complessiva. Fa parte della proposta ECMAScript ed è in fase di implementazione nei principali motori JavaScript.
Vantaggi chiave dell'API Temporal:
- Immutabilità: gli oggetti Temporal sono immutabili, il che significa che le operazioni su di essi restituiscono nuovi oggetti invece di modificare l'originale. Questo aiuta a prevenire effetti collaterali imprevisti e rende il codice più facile da comprendere.
- API chiara: L'API è progettata per essere più intuitiva e coerente rispetto all'oggetto legacy
Date. - Supporto del fuso orario: Temporal fornisce un solido supporto per i fusi orari, consentendoti di lavorare con date e orari in diverse località in tutto il mondo.
- Supporto del calendario: Oltre al calendario gregoriano, l'API consente l'utilizzo di altri sistemi di calendario, facilitando le applicazioni globali.
- Gestione dei secondi intercalari: L'API Temporal tiene conto dei secondi intercalari, fornendo calcoli temporali più accurati.
Iniziare con Temporal
Sebbene l'API Temporal sia ancora in fase di sviluppo e non sia ancora completamente supportata in tutti i browser e negli ambienti Node.js, puoi utilizzare un polyfill per iniziare a sperimentare oggi stesso. Puoi installare il polyfill tramite npm:
npm install @js-temporal/polyfill
Quindi, importa il polyfill nel tuo codice JavaScript:
import { Temporal } from '@js-temporal/polyfill';
Una volta installato il polyfill, puoi iniziare a utilizzare l'oggetto Temporal e le sue varie classi.
Classi Temporali Fondamentali
L'API Temporal fornisce diverse classi chiave per lavorare con date e orari:
Temporal.PlainDate: Rappresenta una data di calendario (anno, mese e giorno) senza alcuna informazione sul fuso orario o sull'ora del giorno.Temporal.PlainTime: Rappresenta un'ora del giorno (ora, minuto, secondo e frazione di secondo) senza alcuna informazione sulla data o sul fuso orario.Temporal.PlainDateTime: Rappresenta una data e un'ora senza alcuna informazione sul fuso orario.Temporal.ZonedDateTime: Rappresenta una data e un'ora con un fuso orario specifico.Temporal.Instant: Rappresenta un punto specifico nel tempo, misurato in nanosecondi dall'epoca Unix (1 gennaio 1970, alle 00:00:00 Tempo Coordinato Universale (UTC)).Temporal.TimeZone: Rappresenta un fuso orario.Temporal.Duration: Rappresenta una durata di tempo, come ore, minuti o secondi.Temporal.Now: Fornisce l'accesso alla data e all'ora correnti.
Lavorare con PlainDate
La classe Temporal.PlainDate rappresenta una data senza alcuna informazione sul fuso orario o sull'ora del giorno. È utile per rappresentare compleanni, anniversari o altri eventi basati sulla data.
Creazione di un PlainDate:
const plainDate = Temporal.PlainDate.from({ year: 2024, month: 10, day: 26 });
console.log(plainDate.toString()); // Output: 2024-10-26
Puoi anche creare un PlainDate da una stringa in formato ISO 8601:
const plainDateFromString = Temporal.PlainDate.from('2024-12-25');
console.log(plainDateFromString.toString()); // Output: 2024-12-25
Accesso ai Componenti della Data:
const year = plainDate.year; // 2024
const month = plainDate.month; // 10
const day = plainDate.day; // 26
const dayOfWeek = plainDate.dayOfWeek; // Giorno della settimana (1-7, Lunedì-Domenica)
const dayOfYear = plainDate.dayOfYear; // Giorno dell'anno (1-366)
const daysInMonth = plainDate.daysInMonth; // Numero di giorni nel mese
const isLeapYear = plainDate.isLeapYear; // Booleano che indica se l'anno è bisestile
Aggiunta e Sottrazione di Giorni:
const nextDay = plainDate.add({ days: 1 });
console.log(nextDay.toString()); // Output: 2024-10-27
const previousWeek = plainDate.subtract({ weeks: 1 });
console.log(previousWeek.toString()); // Output: 2024-10-19
Confronto tra Date:
const anotherDate = Temporal.PlainDate.from({ year: 2024, month: 11, day: 15 });
if (plainDate.equals(anotherDate)) {
console.log('Le date sono uguali');
} else if (plainDate.lessThan(anotherDate)) {
console.log('plainDate è precedente a anotherDate');
} else {
console.log('plainDate è successiva a anotherDate');
}
// Output: plainDate è precedente a anotherDate
Lavorare con PlainTime
La classe Temporal.PlainTime rappresenta un'ora del giorno senza alcuna informazione sulla data o sul fuso orario. È utile per rappresentare orari di apertura, orari di riunione o altri eventi basati sull'ora.
Creazione di un PlainTime:
const plainTime = Temporal.PlainTime.from({ hour: 14, minute: 30, second: 0 });
console.log(plainTime.toString()); // Output: 14:30:00
Puoi anche creare un PlainTime da una stringa in formato ISO 8601:
const plainTimeFromString = Temporal.PlainTime.from('09:00:00');
console.log(plainTimeFromString.toString()); // Output: 09:00:00
Accesso ai Componenti dell'Ora:
const hour = plainTime.hour; // 14
const minute = plainTime.minute; // 30
const second = plainTime.second; // 0
const millisecond = plainTime.millisecond; // 0
const microsecond = plainTime.microsecond; // 0
const nanosecond = plainTime.nanosecond; // 0
Aggiunta e Sottrazione di Tempo:
const laterTime = plainTime.add({ minutes: 15 });
console.log(laterTime.toString()); // Output: 14:45:00
const earlierTime = plainTime.subtract({ hours: 1 });
console.log(earlierTime.toString()); // Output: 13:30:00
Confronto tra Orari:
const anotherTime = Temporal.PlainTime.from({ hour: 15, minute: 0, second: 0 });
if (plainTime.equals(anotherTime)) {
console.log('Gli orari sono uguali');
} else if (plainTime.lessThan(anotherTime)) {
console.log('plainTime è precedente a anotherTime');
} else {
console.log('plainTime è successiva a anotherTime');
}
// Output: plainTime è precedente a anotherTime
Lavorare con PlainDateTime
La classe Temporal.PlainDateTime rappresenta una data e un'ora senza alcuna informazione sul fuso orario. Combina la funzionalità di PlainDate e PlainTime.
Creazione di un PlainDateTime:
const plainDateTime = Temporal.PlainDateTime.from({ year: 2024, month: 10, day: 26, hour: 14, minute: 30, second: 0 });
console.log(plainDateTime.toString()); // Output: 2024-10-26T14:30:00
Puoi anche creare un PlainDateTime da una stringa in formato ISO 8601:
const plainDateTimeFromString = Temporal.PlainDateTime.from('2024-12-25T09:00:00');
console.log(plainDateTimeFromString.toString()); // Output: 2024-12-25T09:00:00
Accesso ai Componenti di Data e Ora:
const year = plainDateTime.year; // 2024
const month = plainDateTime.month; // 10
const day = plainDateTime.day; // 26
const hour = plainDateTime.hour; // 14
const minute = plainDateTime.minute; // 30
const second = plainDateTime.second; // 0
Aggiunta e Sottrazione di Date e Orari:
const nextDayAndTime = plainDateTime.add({ days: 1, hours: 2 });
console.log(nextDayAndTime.toString()); // Output: 2024-10-27T16:30:00
const previousWeekAndTime = plainDateTime.subtract({ weeks: 1, minutes: 30 });
console.log(previousWeekAndTime.toString()); // Output: 2024-10-19T14:00:00
Conversione in PlainDate e PlainTime:
const plainDateFromDateTime = plainDateTime.toPlainDate();
console.log(plainDateFromDateTime.toString()); // Output: 2024-10-26
const plainTimeFromDateTime = plainDateTime.toPlainTime();
console.log(plainTimeFromDateTime.toString()); // Output: 14:30:00
Lavorare con ZonedDateTime
La classe Temporal.ZonedDateTime rappresenta una data e un'ora con un fuso orario specifico. Questo è fondamentale per le applicazioni che devono gestire date e orari in diverse località in tutto il mondo. A differenza dell'oggetto legacy Date, Temporal fornisce supporto integrato per il fuso orario.
Creazione di un ZonedDateTime:
const zonedDateTime = Temporal.ZonedDateTime.from({ year: 2024, month: 10, day: 26, hour: 14, minute: 30, second: 0, timeZone: 'America/Los_Angeles' });
console.log(zonedDateTime.toString()); // Output: 2024-10-26T14:30:00-07:00[America/Los_Angeles]
Puoi anche creare un ZonedDateTime da un Instant e un fuso orario:
const instant = Temporal.Instant.fromEpochSeconds(1666785000); // Timestamp di esempio
const zonedDateTimeFromInstant = instant.toZonedDateTimeISO('Europe/London');
console.log(zonedDateTimeFromInstant.toString()); // L'output varierà in base all'istantaneo effettivo, ma rifletterà la data/ora in Europa/Londra
Accesso ai Componenti di Data e Ora:
const year = zonedDateTime.year; // 2024
const month = zonedDateTime.month; // 10
const day = zonedDateTime.day; // 26
const hour = zonedDateTime.hour; // 14
const minute = zonedDateTime.minute; // 30
const second = zonedDateTime.second; // 0
const timeZone = zonedDateTime.timeZone; // Oggetto Temporal.TimeZone
Conversione tra Fusi Orari:
const newYorkDateTime = zonedDateTime.withTimeZone('America/New_York');
console.log(newYorkDateTime.toString()); // Output: 2024-10-26T17:30:00-04:00[America/New_York]
Gestione dell'Ora Legale (DST):
Temporal gestisce automaticamente le transizioni DST. Quando si aggiunge o si sottrae tempo, tiene conto del DST, garantendo risultati accurati. Ad esempio, considera una riunione programmata durante la transizione DST in Germania:
const meetingStart = Temporal.ZonedDateTime.from({ year: 2024, month: 3, day: 31, hour: 2, minute: 30, timeZone: 'Europe/Berlin' });
const meetingEnd = meetingStart.add({ hours: 1 }); // Aggiunta di 1 ora
console.log(meetingEnd.toString()); // Output: 2024-03-31T03:30:00+02:00[Europe/Berlin]. Si noti che l'offset cambia a causa del DST
Lavorare con Instant
La classe Temporal.Instant rappresenta un punto specifico nel tempo, misurato in nanosecondi dall'epoca Unix. È utile per archiviare e confrontare momenti esatti nel tempo.
Creazione di un Instant:
const instant = Temporal.Instant.fromEpochSeconds(1666785000); // Timestamp Unix di esempio in secondi
console.log(instant.toString()); // L'output sarà una rappresentazione di stringa ISO di quell'istantaneo
Conversione in ZonedDateTime:
const zonedDateTimeFromInstant = instant.toZonedDateTimeISO('America/Los_Angeles');
console.log(zonedDateTimeFromInstant.toString()); // Output: Data e ora in America/Los_Angeles corrispondenti all'istantaneo
Confronto tra Istanti:
const anotherInstant = Temporal.Instant.fromEpochSeconds(1666790000);
if (instant.equals(anotherInstant)) {
console.log('Gli istanti sono uguali');
} else if (instant.lessThan(anotherInstant)) {
console.log('instant è precedente a anotherInstant');
} else {
console.log('instant è successivo a anotherInstant');
}
// Output: instant è precedente a anotherInstant
Lavorare con Duration
La classe Temporal.Duration rappresenta una durata di tempo, come ore, minuti o secondi. È utile per calcolare la differenza tra due date o orari.
Creazione di una Duration:
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
console.log(duration.toString()); // Output: PT2H30M
Calcolo della Differenza tra Date/Orari:
const startDate = Temporal.PlainDateTime.from({ year: 2024, month: 1, day: 1, hour: 0, minute: 0, second: 0 });
const endDate = Temporal.PlainDateTime.from({ year: 2024, month: 1, day: 3, hour: 12, minute: 30, second: 0 });
const difference = endDate.since(startDate);
console.log(difference.toString()); // Output: P2DT12H30M
// Accesso ai componenti della durata
console.log(difference.days); // 2
console.log(difference.hours); // 12
console.log(difference.minutes); // 30
Aggiunta di Durata a Date/Orari:
const newDate = startDate.add(duration);
console.log(newDate.toString()); // Output: 2024-01-03T02:30:00
Lavorare con i Calendari
L'API Temporal supporta diversi sistemi di calendario oltre al calendario gregoriano. Sebbene non sia completamente implementato in tutti i polyfill e i motori, l'intenzione è quella di consentire alle applicazioni di gestire le date in calendari specifici per varie culture. Ad esempio, per utilizzare il calendario giapponese (ipoteticamente, poiché l'implementazione è ancora in evoluzione):
// Questo è un esempio concettuale poiché il supporto del calendario è ancora in fase di sviluppo
// const japaneseDate = Temporal.PlainDate.from({ year: 2024, month: 10, day: 26, calendar: 'japanese' });
// console.log(japaneseDate.toString()); // Previsto: output formattato in base al calendario giapponese
Nota: Il supporto del calendario è una funzionalità in evoluzione dell'API Temporal e la piena funzionalità non è ancora universalmente disponibile.
Esempi Pratici e Casi d'Uso
L'API Temporal offre una vasta gamma di possibilità per la gestione di date e orari in JavaScript. Ecco alcuni esempi pratici e casi d'uso:
- Pianificazione di Appuntamenti: Crea un'applicazione di pianificazione che consente agli utenti di prenotare appuntamenti nel loro fuso orario locale. Temporal.ZonedDateTime semplifica la conversione tra fusi orari e la gestione delle transizioni DST. Per una clinica a Berlino che pianifica appuntamenti a livello globale:
- Calcolo dell'Età: Determina l'età di un utente in base alla sua data di nascita. PlainDate ti consente di rappresentare la data di nascita senza alcuna informazione sul fuso orario.
- Visualizzazione di Date e Orari in Diversi Formati: Formatta date e orari in base alle impostazioni locali dell'utente. Sebbene le funzionalità di internazionalizzazione (Intl) siano separate, gli oggetti Temporal possono essere facilmente formattati utilizzando
toLocaleString()o metodi simili se combinati con le funzionalità dell'API Intl. - Monitoraggio della Durata degli Eventi: Calcola la durata di un evento e visualizzala in un formato leggibile. Duration ti consente di rappresentare la differenza di tempo tra due date o orari.
const appointmentTimeBerlin = Temporal.ZonedDateTime.from({ year: 2024, month: 11, day: 5, hour: 10, minute: 0, timeZone: 'Europe/Berlin' });
const appointmentTimeLA = appointmentTimeBerlin.withTimeZone('America/Los_Angeles');
console.log(`Orario dell'appuntamento a Berlino: ${appointmentTimeBerlin.toString()}`);
console.log(`Orario dell'appuntamento a Los Angeles: ${appointmentTimeLA.toString()}`);
const birthDate = Temporal.PlainDate.from({ year: 1990, month: 5, day: 15 });
const today = Temporal.Now.plainDateISO();
const age = today.year - birthDate.year - (today.month < birthDate.month || (today.month === birthDate.month && today.day < birthDate.day) ? 1 : 0);
console.log(`Età: ${age}`);
const zonedDateTimeNow = Temporal.Now.zonedDateTimeISO('en-GB');
console.log(zonedDateTimeNow.toLocaleString('en-GB'));
console.log(zonedDateTimeNow.toLocaleString('de-DE'));
const eventStart = Temporal.Instant.fromEpochSeconds(1700000000); // Timestamp di inizio esempio
const eventEnd = Temporal.Instant.fromEpochSeconds(1700005000); // Timestamp di fine esempio
const durationOfEvent = eventEnd.since(eventStart);
console.log(`Durata dell'evento: ${durationOfEvent.minutes} minuti`);
Best Practice per l'Utilizzo dell'API Temporal
Ecco alcune best practice da tenere a mente quando si utilizza l'API Temporal:
- Usa l'Immutabilità: Adotta l'immutabilità degli oggetti Temporal. Evita di modificare direttamente gli oggetti. Invece, crea nuovi oggetti utilizzando metodi come
add,subtractewith. - Gestisci Attentamente i Fusi Orari: Presta attenzione ai fusi orari quando lavori con date e orari. Usa
ZonedDateTimequando devi rappresentare date e orari in un fuso orario specifico. - Usa Nomi di Variabili Chiari: Usa nomi di variabili descrittivi che indichino chiaramente il tipo di oggetto Temporal utilizzato (ad es.
plainDate,zonedDateTime,duration). - Considera i Polyfill: Poiché Temporal è ancora relativamente nuovo, assicurati un supporto sufficiente utilizzando una libreria polyfill quando necessario.
- Valida l'Input: Valida sempre l'input dell'utente per assicurarti che date e orari siano nel formato corretto.
Migrazione dalla Data Legacy
La migrazione dall'oggetto legacy Date può essere un processo graduale. Considera queste strategie:
- Adozione Incrementale: Inizia utilizzando Temporal nel nuovo codice mantenendo
Datenelle parti esistenti della tua applicazione. - Funzioni Wrapper: Crea funzioni wrapper che convertono tra oggetti
Datee Temporal per facilitare l'interoperabilità durante la migrazione. - Test Approfonditi: Esegui test approfonditi della migrazione per assicurarti che tutti i calcoli di data e ora siano accurati.
API Temporal vs. Moment.js
Moment.js era una libreria popolare per la manipolazione di date e orari in JavaScript, ma ora è considerato un progetto legacy ed è in modalità di manutenzione. L'API Temporal fornisce una soluzione più moderna e standardizzata che affronta molte delle carenze di Moment.js. Moment.js è mutabile e manca del supporto nativo del fuso orario. L'API Temporal è immutabile e ha il supporto nativo del fuso orario.
Conclusione
L'API Temporal di JavaScript rappresenta un miglioramento significativo rispetto all'oggetto legacy Date. La sua immutabilità, l'API chiara, il supporto del fuso orario e il supporto del calendario lo rendono uno strumento potente per la gestione di date e orari nelle moderne applicazioni JavaScript. Sebbene l'adozione sia ancora in crescita, l'utilizzo di un polyfill ti consente di iniziare a sfruttarne i vantaggi oggi stesso. Man mano che l'API diventa più ampiamente supportata, si prevede che diventerà il modo standard per lavorare con date e orari in JavaScript.
Abbraccia l'API Temporal e sblocca un modo più efficiente e affidabile per gestire date e orari nei tuoi progetti, assicurandoti che la tua applicazione gestisca accuratamente i fusi orari globali e i calcoli.